import schedule
import time
import shutil
import os
from datetime import datetime

def perform_backup(source_dir, backup_dir):
    """
    这个函数负责执行一次完整的备份操作。
    它会将源文件夹压缩成一个带时间戳的 .zip 文件，并存放到备份目录中。

    :param source_dir: 需要被备份的文件夹路径。
    :param backup_dir: 存放备份文件的文件夹路径。
    """
    # 1. 安全检查：确保源文件夹真的存在
    if not os.path.isdir(source_dir):
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 错误：源目录 '{source_dir}' 不存在，跳过本次备份。")
        return

    # 2. 创建一个独一无二的备份文件名 (包含日期和时间)
    #    例如: backup_2025-11-01_22-30-05
    timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    backup_filename_base = f"backup_{timestamp}"

    # 3. 构造最终的备份文件存放路径 (不含.zip后缀)
    destination_path = os.path.join(backup_dir, backup_filename_base)

    # 4. 打印日志，告知用户操作正在进行
    print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 正在备份 '{source_dir}' 到 '{destination_path}.zip'...")

    # 5. 使用 shutil.make_archive() 这个强大的函数来完成压缩
    #    它会自动创建 .zip 文件
    try:
        shutil.make_archive(
            base_name=destination_path,  # 压缩包的文件路径(不含后缀)
            format='zip',                # 压缩格式为 zip
            root_dir=source_dir          # 需要被压缩的文件夹
        )
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 备份成功！")
    except Exception as e:
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 备份失败: {e}")


# --- 主程序入口 ---
if __name__ == '__main__':
    # --- 在这里进行配置 ---
    source_folder = 'important_data'  # 你想要备份的文件夹名称
    backup_folder = 'backups'         # 用于存放所有备份压缩包的文件夹名称

    # --- 准备工作：确保源文件夹和备份文件夹都存在 ---
    # 如果文件夹不存在，就创建它
    os.makedirs(source_folder, exist_ok=True)
    os.makedirs(backup_folder, exist_ok=True)

    print("定时备份任务已启动。")
    print(f"源文件夹: '{os.path.abspath(source_folder)}'")
    print(f"备份至:   '{os.path.abspath(backup_folder)}'")
    print("按 Ctrl+C 可以随时停止程序。")

    # --- 设置定时任务 ---
    # schedule.every(10).seconds.do(...) # 每10秒执行一次 (用于测试)
    # schedule.every(1).minutes.do(...)   # 每分钟执行一次
    schedule.every(1).hours.do(perform_backup, source_dir=source_folder, backup_dir=backup_folder) # 每小时执行一次
    # schedule.every().day.at("02:00").do(...) # 每天凌晨2点执行一次

    # 为了方便您测试，我们先设置为每10秒执行一次
    schedule.every(10).seconds.do(perform_backup, source_dir=source_folder, backup_dir=backup_folder)

    # --- 任务调度循环 ---
    # 这是一个无限循环，程序会一直在这里运行，
    # schedule库会在这里检查是否有已到时间的任务需要执行。
    try:
        while True:
            schedule.run_pending()  # 检查并运行所有待执行的任务
            time.sleep(1)           # 等待1秒，避免CPU占用过高
    except KeyboardInterrupt:
        print("\n程序已手动停止。")